------------------------------------------------------------------------------
-- State machine library for computercraft's scripts by Hea3veN
-- Version 0.1
------------------------------------------------------------------------------

loadfile("lib/status.lua")()
os.loadAPI("api/logf")

function smStart(progStates)
	if statusGetProgData().state == nil then
		logf.logf(logf.INFO, 'state-machine', 'Starting a new run')
		statusGetProgData().state = 'init'
		statusGetProgData().prevState = 'init'
		statusGetProgData().pause = false
		statusSave()
	else
		logf.logf(logf.INFO, 'state-machine', 'Continuing a previous run from the state "'..statusGetProgData().state..'"')
	end

	os.startTimer(0.2)
	while true do
		event, param1, param2, param3 = os.pullEvent()
		
		if event == "key" then
			logf.logf(logf.DEBUG, 'state-machine', 'Key '..param1..' pressed')
			if param1 == 25 then
				-- "p" key
				statusGetProgData().pause = not statusGetProgData().pause;
				statusSave()
				if not statusGetProgData().pause then
					logf.logf(logf.INFO, 'state-machine', 'Unpausing')
					os.startTimer(0.2)
				else
					logf.logf(logf.INFO, 'state-machine', 'Pausing')
					os.sleep(2)
				end
			end
			if param1 == 28 then
				-- Enter key
			end
			if param1 == 31 then
				-- "s" key
				logf.logf(logf.INFO, 'state-machine', 'Stopping');
				statusGetProgData().pause = true;
				statusSave()
				return
			end
			if param1 == 37 then
				-- "k" key
				logf.logf(logf.INFO, 'state-machine', 'Killing');
				statusEnd()
				return
			end
		elseif event == "timer" then
			if not statusGetProgData().pause then
				state = statusGetProgData().state
				
				if state == 'stop' then
					logf.logf(logf.INFO, 'state-machine', 'Stopping');
					statusGetProgData().pause = true;
					statusGetProgData().state = statusGetProgData().prevState
					statusSave()
					return
				elseif state == 'end' then
					logf.logf(logf.INFO, 'state-machine', 'Ending');
					statusEnd()
					return
				else
					--for k,v in pairs(progStates) do
					--	print("state: " ..tostring(k))
					--end
					stateFunc = progStates[state]
				
					if stateFunc == nil then
						logf.logf(logf.ERROR, 'state-machine', 'Reached an undefined state "'..tostring(state)..'"')
						statusGetProgData().prevState = state
						statusGetProgData().state = 'stop'
						statusSave()
					else
						logf.logf(logf.DEBUG, 'state-machine', 'Running the state "'..tostring(state)..'"')
						nextState = stateFunc()
						statusGetProgData().prevState = state
						statusGetProgData().state = nextState
						statusSave()
					end
				end
				os.startTimer(0.2)
			end
		end
	end
end

